package com.woniuxy.amusementparkos.realm;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.woniuxy.amusementparkos.config.ShiroConfiguration;
import com.woniuxy.amusementparkos.entity.fzw.User;
import com.woniuxy.amusementparkos.service.fzw.UserService;
/**
 * 自定义Realm
 *权限验证+身份验证，并在配置类中配置了内置缓存
 *
 * @author fzw
 *
 * 2020年4月27日下午4:08:12
 */
public class UserRealm extends AuthorizingRealm{
	private static final Logger logger = LoggerFactory.getLogger(UserRealm.class);
	@Autowired
	private UserService userService;
	/**
	 * 权限验证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		//获取username
		String principal = (String) principals.getPrimaryPrincipal();
		//角色查询
		Collection<String> rolesByUsername=userService.selectAllRoleByUsername(principal);
		//角色存放
		Set<String> roles = new HashSet<String>();
		for(String roleName:rolesByUsername) {
			roles.add(roleName);
		}
		//根据角色查询权限
		//权限采用Shiro官方推荐的多层次写法，如user:select
		Collection<String> permissions = userService.selectAllPermissionByRoles(rolesByUsername);
		authorizationInfo.addStringPermissions(permissions);
		authorizationInfo.setRoles(roles);
		return authorizationInfo;
	}
	/**
	 * 身份验证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken mytoken = (UsernamePasswordToken) token;
		if(mytoken==null) {
			logger.info("======user认证信息为空=======");
			return null;
		}
		//获取提交的用户名
		String username = mytoken.getUsername();
		//检查用户名，若不存在，则返回null，Shrio会抛出异常
		User realUser=userService.selectOneUserByName(username);
		if(realUser==null) {
			return null;
		}
		//获取该用户的盐值，并和用户名混合
		ByteSource salt = ByteSource.Util.bytes(realUser.getSalt()+username);
		//打印盐值
//		System.out.println(salt);
		//查询数据库对应该用户的真实密码
		String realPassword = userService.selectPasswordByUsername(username);
		//测试用混合盐和密码进行MD5加密并迭代1024次和数据库密码对比
//		String ciphertext = new Md5Hash("123456",salt,1024).toString();
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,realPassword,salt,this.getName());
		return info;
	}
	
}
